package com.iot.ic.utils.response;


import com.iot.ic.common.CustomException;
import com.iot.ic.common.Options;
import com.iot.ic.utils.DatetimeUtil;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @author xiuge
 * @Description:返回信息工具类
 * @date 2016年7月4日上午10:04:50
 */
public class ResponseUtil {

    /**
     * 根据POJO类属性名列表和对象，返回一个包含相应属性和值的Map
     *
     * @param model    对象
     * @param nameList 属性名称列表
     * @param isParse  是否解析部分参数（包括添加Option信息，时间戳转字符串，Date类型转字符串）
     * @return
     */
    public static Map<String, Object> getResultMap(Object model, List<String> nameList, boolean isParse) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            String className = model.getClass().getName();
            if (className.contains("$$")) {
                className = className.substring(0, className.indexOf("$$"));
            }
            Class clazz = Class.forName(className);// 根据类名获得其对应的Class对象 写上你想要的类名
            Field[] fields = clazz.getDeclaredFields();// 根据Class对象获得属性 私有的也可以获得
            List<Field> fieldList = Arrays.asList(fields);
            for (Field field : fieldList) {
                String name = field.getName();
                if (nameList.contains(name)) {
                    addInfoToMap(model, field, map, isParse);
                }
            }
            Class superclass = clazz.getSuperclass();
            if (superclass.getName().contains("com.iot.model.Record")) {
                Field[] childFields = superclass.getDeclaredFields();
                List<Field> superFieldList = Arrays.asList(childFields);
                for (Field field : superFieldList) {
                    String name = field.getName();
                    if (nameList.contains(name)) {
                        addInfoToMap(model, field, map, isParse);
                    }
                }
            }

        } catch (Exception e) {
            throw new CustomException("Map信息解析错误！");
        }
        return map;
    }


    /**
     * POJO类所有字段信息保存到map中
     *
     * @param model
     * @param isParse
     * @return
     */
    public static Map<String, Object> getResultMap(Object model, boolean isParse) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            String className = model.getClass().getName();
            if (className.contains("$$")) {
                className = className.substring(0, className.indexOf("$$"));
            }
            Class clazz = Class.forName(className);// 根据类名获得其对应的Class对象 写上你想要的类名
            Field[] fields = clazz.getDeclaredFields();// 根据Class对象获得属性 私有的也可以获得
            List<Field> fieldList = Arrays.asList(fields);
            for (Field field : fieldList) {
                addInfoToMap(model, field, map, isParse);
            }
            Class superClass = clazz.getSuperclass();
            if (superClass.getName().contains("com.iot.model.Record")) {
                Field[] superFields = superClass.getDeclaredFields();
                List<Field> superFieldList = Arrays.asList(superFields);
                for (Field field : superFieldList) {
                    addInfoToMap(model, field, map, isParse);
                }
            }
        } catch (Exception e) {
            throw new CustomException("Map信息解析错误！");
        }
        return map;
    }

    /**
     * 首字符大写
     *
     * @param str
     * @return
     */
    public static String firstLetterToUpper(String str) {
        char[] array = str.toCharArray();
        array[0] -= 32;
        return String.valueOf(array);
    }

    /**
     * 把信息添加到map中
     *
     * @param model
     * @param field
     * @param map
     * @param isParse
     * @return
     */
    private static Map<String, Object> addInfoToMap(Object model, Field field, Map<String, Object> map, boolean isParse) {
        try {
            Class a = field.getType();
            String paramType = a.getName();
            String name = field.getName();
            Method m = model.getClass().getMethod("get" + firstLetterToUpper(name));// 根据方法名称获取对应属性
            if (isParse) {
                if (paramType.equals("java.util.Date")) {//Date类型的数据转换成时间字符串返回
                    Date timeStamp = (Date) m.invoke(model);
                    if (timeStamp != null) {
                        map.put(name, timeStamp.getTime());
                        map.put(name + "Info", DatetimeUtil.timeStampToDate(timeStamp.getTime() / 1000, null));
                    } else {
                        map.put(name, "");
                        map.put(name + "Info", "");
                    }
                } else if (paramType.equals("java.lang.Byte")) {//Byte类型的数据根据Option类转化成对应的选项
                    if (name.contains("detailType")) {//当model为ExceptionRecord类时，detailType的值要根据exceptionType的值设置
                        Method exceptionTypeMethod = model.getClass().getMethod("getExceptionType");
                        Byte exceptionType = (Byte) exceptionTypeMethod.invoke(model);
                        name += exceptionType;
                    }
                    Integer optionCode = (Integer) m.invoke(model);
                    String option = Options.getDescByTag(optionCode, name);
                    if (option.equals("")) {
                        map.put(name, optionCode);//识别不出对应的Option，则返回原值
                        map.put(name + "Info", "");//返回选项说明为空
                    } else {
                        map.put(name, optionCode);
                        map.put(name + "Info", option);//返回选项说明
                    }

                } else if (name.contains("Time") && paramType.equals("java.lang.Long")) {//时间戳转字符串
                    Long createTime = (Long) m.invoke(model);
                    map.put(name, DatetimeUtil.timeStampToDate(createTime, null));
                } else {
                    map.put(name, m.invoke(model));
                }
            } else {
                map.put(name, m.invoke(model));
            }
        } catch (Exception e) {
            throw new CustomException("Map信息解析错误！");
        }
        return map;
    }

}
